home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Graphics / RTGmaster / demos / moon / RTGGadgets.c < prev    next >
C/C++ Source or Header  |  1996-08-08  |  26KB  |  962 lines

  1. /*
  2.  *  RTGGadgets  V1.2
  3.  *
  4.  *
  5.  *  A package to use gadget-like input elements on RTG screens
  6.  *
  7.  *  Copyright © 1996 by Thomas and Hans-Joerg Frieden
  8.  *  Written by Thomas and Hans-Joerg Frieden
  9.  *
  10.  *  This software may be freely distributed. The copyright remains with
  11.  *  the copyright holders. For further information, see legal.doc
  12.  *  In no way may this software be modified without permission of the
  13.  *  copyright holders.
  14.  *
  15.  *  This software is provided "as is", and may only be used at your own risk.
  16.  *  The copyright holder and/or the authors can not be held responible for any
  17.  *  damage the usage of this software may cause. To put it in other words, we are not
  18.  *  responisble if your cat dies while using this software.
  19.  *
  20.  *  Version         Comment
  21.  *  --------------------------------------------------------------
  22.  *  0.1             Initial Version without custom functions
  23.  *  1.0             Custom functions inserted
  24.  *  1.1             Mouse handling moved to custom input handler, cleanups
  25.  *  1.2             Added keypress gadget activation
  26.  *
  27.  */
  28.  
  29. #include <clib/console_protos.h>
  30. #include "global.h"
  31. #include "RTGGadgets.h"
  32.  
  33. extern struct RTGMasterBase *RTGMasterBase;
  34. extern struct Library *UtilityBase;
  35.  
  36. struct MsgPort *RTGInputMsgPort;
  37. struct IOStdReq *RTGInputIO;
  38. struct Interrupt InputHandler;
  39. RTGInpRec RTGInputRecord;
  40. struct Device *ConsoleDevice;
  41. struct IOStdReq RTGConsoleIO;
  42. struct InputEvent RTGIe;
  43.  
  44.  
  45. struct TagItem mtag[] = {
  46.     grd_MouseX,         0,
  47.     grd_MouseY,         0,
  48.     TAG_DONE,           0
  49. };
  50.  
  51. struct TagItem ctag[] = {
  52.     grd_ColorSpace, 0,
  53.     grd_BytesPerRow,0,
  54.     TAG_DONE,       0
  55. };
  56.  
  57.  
  58. /****** RTGGadgets/CreateRTGGList  ******************************************
  59. *
  60. *   NAME   
  61. *       CreateRTGGList  --  Create and initialize RTGGList header
  62. *
  63. *   SYNOPSIS
  64. *       GList = CreateRTGGList( screen, flags)
  65. *
  66. *       struct RTGGList *CreateRTGGList( struct RTGScreen *, int);
  67. *
  68. *   FUNCTION
  69. *       Allocate RTGGList header and initialize it.
  70. *
  71. *   INPUTS
  72. *       screen = Pointer to an initialized RTGScreen
  73. *       flags  = flags for this screens gadget list
  74. *
  75. *   RESULT
  76. *       A pointer to the RTGGList structure, or zero if there was an error
  77. *
  78. *****************************************************************************
  79. */
  80.  
  81. struct RTGGList *CreateRTGGList(struct RtgScreen *scr, int flags) {
  82.  
  83.     struct RTGGList *createme;
  84.  
  85.     if (!scr) return(NULL);
  86.  
  87.     createme = malloc(sizeof(struct RTGGList));
  88.  
  89.     if (!createme) return(NULL);
  90.  
  91.     createme->gl_First  = NULL;
  92.     createme->gl_Hit    = NULL;
  93.     createme->gl_Selected = NULL;
  94.     createme->gl_Screen = scr;
  95.     createme->gl_Buffer = 0;
  96.     createme->gl_Mode   = TRUE;
  97.     createme->gl_Flags  = flags;
  98.     createme->gl_Reset  = NULL;
  99.  
  100.     return(createme);
  101. }
  102.  
  103. /****** RTGGadgets/CreateRTGGadgetA ******************************************
  104. *
  105. *   NAME
  106. *       CreateRTGGadgetA -- Allocate and initialize an RTG Gadget
  107. *
  108. *   SYNOPSIS
  109. *       result = CreateRTGGadgetA(list, id, tags);
  110. *
  111. *       int CreateRTGGadgetA(struct RTGGList, int, struct TagItem *);
  112. *
  113. *   FUNCTION
  114. *       Create an RTG Gadget with id in list list
  115. *
  116. *   INPUTS
  117. *       list - pointer to an RTG gadget list
  118. *       id   - Unique identification number of this gadget
  119. *       tags - pointer to a tag list. The tagitems are as follows:
  120. *
  121. *           RGADT_LeftEdge      Left edge of gadget (x coordinate)
  122. *           RGADT_TopEdge       Top edge of gadget (y coordinate)
  123. *           RGADT_Width         Width of gadget
  124. *           RGADT_Height        Height of gadget
  125. *           RGADT_Flags         Flags. See below.
  126. *           RGADT_HitTest       Custom function for hit testing
  127. *           RGADT_HitRender     Custom function for rendering hit gadget
  128. *           RGADT_DownRender    Custom function for rendering pressed gadget
  129. *           RGADT_UpRender      Custom function for rendering depressed gadget
  130. *           RGADT_Force         Force this gadet id. Error if already present
  131. *           RGADT_HitPen        Set the hit pen for the standard renderer
  132. *           RGADT_UpPen         Set up pen
  133. *           RGADT_DownPen       Set down pen
  134. *           RGADT_Key           key to activate gadget
  135. *
  136. *
  137. *       The flags field can have the following values:
  138. *
  139. *           RGADF_HITHILITE     The gadget is hihglited when the mouse is
  140. *                               positioned above it.
  141. *
  142. *   RESULT
  143. *       The result is the gadgets id, or -1 if ther was an error.
  144. *       An error also occurs if the gadget`s id was already in use while
  145. *       setting the RGADT_Force tag to TRUE.
  146. *
  147. *   NOTE
  148. *       The key to activate the gadget is the latin 1 representation, not
  149. *       the rawkey code.
  150. *
  151. *****************************************************************************
  152. */
  153.  
  154.  
  155. int CreateRTGGadgetA(struct RTGGList *list, int id,  struct TagItem *tags) {
  156.  
  157.     struct TagItem *tag;
  158.     struct TagItem *tstate;
  159.     struct RTGGadget *do_me;
  160.     struct RTGGadget *akt;
  161.     BOOL force = TRUE;
  162.     BOOL fail = FALSE;
  163.  
  164.     if (!list) return(-1);
  165.  
  166.     GetRtgScreenData(list->gl_Screen, ctag);
  167.  
  168.     do_me = malloc(sizeof(struct RTGGadget));
  169.  
  170.     if (!do_me) return(-1);
  171.  
  172.     do_me->rg_ID        = id;       //  Default values
  173.     do_me->rg_Left      = 0;
  174.     do_me->rg_Top       = 0;
  175.     do_me->rg_Width     = 8;
  176.     do_me->rg_Height    = 8;
  177.     do_me->rg_Flags     = 0;
  178.     do_me->rg_HitTest   = NULL;
  179.     do_me->rg_HitRender = NULL;
  180.     do_me->rg_DownRender= NULL;
  181.     do_me->rg_UpRender  = NULL;
  182.     do_me->rg_UserData  = NULL;
  183.     do_me->rg_ExtHandle = NULL;
  184.     do_me->rg_Key       = 0;
  185.  
  186.     switch (ctag[0].ti_Data) {
  187.         case grd_Palette:
  188.             do_me->rg_HitPen    =   1;
  189.             do_me->rg_DownPen   =   2;
  190.             do_me->rg_UpPen     =   3;
  191.             break;
  192.         default:
  193.             do_me->rg_HitPen    =   0x0f00;
  194.             do_me->rg_DownPen   =   0x00f0;
  195.             do_me->rg_UpPen     =   0x0fff;
  196.             break;
  197.     }
  198.  
  199.     //  Now parse tag list
  200.  
  201.     tstate = tags;
  202.  
  203.     while ( tag = NextTagItem(&tstate)) {
  204.         switch (tag->ti_Tag) {
  205.             case RGADT_LeftEdge:
  206.                 do_me->rg_Left = (int)(tag->ti_Data);
  207.                 break;
  208.             case RGADT_TopEdge:
  209.                 do_me->rg_Top = (int)(tag->ti_Data);
  210.                 break;
  211.             case RGADT_Width:
  212.                 do_me->rg_Width = (int)(tag->ti_Data);
  213.                 break;
  214.             case RGADT_Height:
  215.                 do_me->rg_Height = (int)(tag->ti_Data);
  216.                 break;
  217.             case RGADT_Flags:
  218.                 do_me->rg_Flags = (int)(tag->ti_Data);
  219.                 break;
  220.             case RGADT_HitTest:
  221.                 do_me->rg_HitTest = (void *)(tag->ti_Data);
  222.                 break;
  223.             case RGADT_HitRender:
  224.                 do_me->rg_HitRender = (void *)(tag->ti_Data);
  225.                 printf("Read: %x, Inserted: %x\n",tag->ti_Data, do_me->rg_HitRender);
  226.                 break;
  227.             case RGADT_DownRender:
  228.                 do_me->rg_DownRender = (void *)(tag->ti_Data);
  229.                 break;
  230.             case RGADT_UpRender:
  231.                 do_me->rg_UpRender = (void *)(tag->ti_Data);
  232.                 break;
  233.             case RGADT_Force:
  234.                 force = (BOOL)(tag->ti_Data);
  235.                 break;
  236.             case RGADT_HitPen:
  237.                 do_me->rg_HitPen = (int)(tag->ti_Data);
  238.                 break;
  239.             case RGADT_UpPen:
  240.                 do_me->rg_UpPen = (int)(tag->ti_Data);
  241.                 break;
  242.             case RGADT_DownPen:
  243.                 do_me->rg_DownPen = (int)(tag->ti_Data);
  244.                 break;
  245.             case RGADT_UserData:
  246.                 do_me->rg_UserData = (APTR)(tag->ti_Data);
  247.                 break;
  248.             case RGADT_Key:
  249.                 do_me->rg_Key = (char)(tag->ti_Data);
  250.                 break;
  251.         }   // switch
  252.     }   // while
  253.  
  254.     if (!list->gl_First) {
  255.         list->gl_First = do_me;
  256.         do_me->rg_Next = NULL;
  257.         return(id);
  258.     }
  259.  
  260.     akt = list->gl_First;                   //  Scan the gadget list
  261.     while (akt->rg_Next) {
  262.         if (akt->rg_ID == id) {             //  id already in use
  263.             if (force) {
  264.                 fail = TRUE;
  265.                 break;
  266.             } else
  267.                 id = INT_MAX;
  268.         }
  269.         if (akt->rg_Next->rg_ID > id)       //  insert here
  270.             break;
  271.         akt = akt->rg_Next;
  272.     }
  273.  
  274.     if (fail) {                             //  We already have this id
  275.         free(do_me);                        //  and want to enforce it, so
  276.         return(-1);                         //  we fail :(
  277.     }
  278.  
  279.     if (id == INT_MAX) {                    //  if id was already in use
  280.         id = akt->rg_ID + 1;                //  use the next free one
  281.         do_me->rg_ID = id;
  282.     }
  283.  
  284.  
  285.     do_me->rg_Next = akt->rg_Next;          //  Put it into the list
  286.     akt->rg_Next = do_me;
  287.  
  288.     return(id);
  289. }
  290.  
  291.  
  292. int CreateRTGGadget(struct RTGGList *list, int id,  Tag tags, ...) {
  293.     return (CreateRTGGadgetA(list, id, (struct TagItem *)&tags));
  294. }
  295.  
  296.  
  297. /****** RTGGadgets/DeleteRTGGadget ******************************************
  298. *
  299. *   NAME   
  300. *       DeleteRTGGadget -- Delete an RTG gadget from the list
  301. *
  302. *   SYNOPSIS
  303. *       id = DeleteRTGGadget(list, id);
  304. *
  305. *       int DeleteRTGGadget(struct RTGGList, int);
  306. *
  307. *   FUNCTION
  308. *       Delete RTG gadget from list.
  309. *
  310. *   INPUTS
  311. *       list - pointer to a struct RTGGList
  312. *       id   - identification number of the gadget to be deleted
  313. *
  314. *   RESULT
  315. *       The result is the id of the removed gadget.
  316. *
  317. *****************************************************************************
  318. */
  319.  
  320.  
  321. int DeleteRTGGadget(struct RTGGList *list, int id) {
  322.  
  323.     struct RTGGadget *akt;
  324.     struct RTGGadget *killme;
  325.  
  326.     if (!list) return(-1);
  327.  
  328.     if (!list->gl_First)                            //  List is empty
  329.         return(-1);
  330.  
  331.     akt = list->gl_First;                           //  Search in list
  332.     if (akt->rg_ID != id) {
  333.         while(akt->rg_Next) {
  334.             if (akt->rg_Next->rg_ID == id)
  335.                 break;
  336.             akt = akt->rg_Next;
  337.         }
  338.     }
  339.  
  340.     if (!akt->rg_Next)                              //  Not found
  341.         return(-1);
  342.  
  343.     killme = akt->rg_Next;
  344.     akt->rg_Next = akt->rg_Next->rg_Next;
  345.     free(killme);
  346.  
  347.     return(id);
  348. }
  349.  
  350.  
  351. /****** RTGGadgets/RTGGHitTest ******************************************
  352. *
  353. *   NAME   
  354. *       RTGGHitTest -- Test gadget hitbox against mouse coordinates
  355. *
  356. *   SYNOPSIS
  357. *       RTGGHitTest(akt, x, y);
  358. *
  359. *       int RTGGHitTest(struct RTGGadget *, int, int);
  360. *
  361. *   FUNCTION
  362. *       This function tests if the point given by x,y is inside the gadget`s
  363. *       hit box.
  364. *       This function is called automatically by RefreshRTGGList.
  365. *       It can be replaced by a user-defined function for more complicated
  366. *       or special cases.
  367. *
  368. *   INPUTS
  369. *       akt - Gadget to test
  370. *       x   - x coordinate of test point
  371. *       y   - y coordinate of test point
  372. *
  373. *   RESULT
  374. *       0 - no hit
  375. *       1 - hit
  376. *
  377. *   NOTES
  378. *
  379. *
  380. *****************************************************************************
  381. *
  382. */
  383.  
  384.  
  385. int RTGGHitTest(struct RTGGadget *akt, int x, int y) {
  386.  
  387.     if (!akt) return(0);
  388.  
  389.     if (akt->rg_HitTest) {
  390.         return(akt->rg_HitTest(akt, x, y));
  391.     }
  392.  
  393.     if (x <= akt->rg_Left) return(0);
  394.     if (x >= akt->rg_Left + akt->rg_Width) return(0);
  395.     if (y <= akt->rg_Top)  return(0);
  396.     if (y >= akt->rg_Top + akt->rg_Height) return(0);
  397.     return(1);
  398. }
  399.  
  400.  
  401. /*
  402.  *
  403.  *  DrawRTGBox
  404.  *
  405.  */
  406.  
  407. void DrawRTGBox(struct RtgScreen *scr, APTR badr, int x, int y, int w, int h, char c) {
  408.  
  409.     int i;
  410.     int bpr;
  411.     char *l1, *l2;
  412.  
  413.     GetRtgScreenData(scr, ctag);
  414.  
  415.     bpr = ctag[1].ti_Data;
  416.  
  417.     l1 = (char *)(y * bpr + x + (char *)badr);
  418.     l2 = (char *)((y + h) * bpr + x+ (char *)badr) ;
  419.  
  420.     for(i = 0; i < w; i++) {
  421.         *l1 = c;
  422.         *l2 = c;
  423.         l1++; l2 ++;
  424.     }
  425.  
  426.     l1 = (char *)(y * bpr + x + (char *)badr);
  427.     l2 = (char *)(y * bpr + x + w + (char *)badr);
  428.  
  429.     for(i = 0; i <= h; i++) {
  430.         *l1 = c;
  431.         *l2 = c;
  432.         l1 += bpr;
  433.         l2 += bpr;
  434.     }
  435. }
  436.  
  437.  
  438. /****** RTGGadget/RTGGHitRender ******************************************
  439. *
  440. *   NAME   
  441. *       RTGGHitRender -- Render gadget in hit position
  442. *
  443. *   SYNOPSIS
  444. *       RTGGHitRender(list, akt);
  445. *
  446. *       RTGGHitRender(struct RTGGlist *, struct RTGGadget *);
  447. *
  448. *   FUNCTION
  449. *       Render gadget in hit position (i.e. pointer is over gadget)
  450. *       This function is called by RefreshRTGGList.
  451. *       It can be replaced by a custom function.
  452. *
  453. *   INPUTS
  454. *       list - pointer ot gadget list
  455. *       akt  - pointer to gadget
  456. *
  457. *
  458. *****************************************************************************
  459. *
  460. */
  461.  
  462.  
  463. void RTGGHitRender(struct RTGGList *list, struct RTGGadget *akt) {
  464.  
  465.     APTR badr;
  466.     int x,y,w,h;
  467.  
  468.     if (!list) return;
  469.  
  470.     if (!(akt->rg_Flags & RGADF_HITHILITE)) return;
  471.  
  472.     if (akt->rg_HitRender) {
  473.         akt->rg_HitRender(list, akt);
  474.         return;
  475.     }
  476.  
  477.     GetRtgScreenData(list->gl_Screen, ctag);
  478.     badr = GetBufAdr(list->gl_Screen, list->gl_Buffer);
  479.  
  480.     x = akt->rg_Left;
  481.     y = akt->rg_Top;
  482.     w = akt->rg_Width;
  483.     h = akt->rg_Height;
  484.  
  485.     if (ctag[0].ti_Data == grd_Palette) {
  486. /*        DrawRtgLine(list->gl_Screen, badr, akt->rg_HitPen, x, y, x+w, y);
  487.         DrawRtgLine(list->gl_Screen, badr, akt->rg_HitPen, x, y+h, x+w, y+h);
  488.         DrawRtgLine(list->gl_Screen, badr, akt->rg_HitPen, x, y, x, y+h);
  489.         DrawRtgLine(list->gl_Screen, badr, akt->rg_HitPen, x+w, y, x+w, y+h);*/
  490.         DrawRTGBox(list->gl_Screen, badr, x, y, w, h, akt->rg_HitPen);
  491.     } else {
  492.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_HitPen, x, y, x+w, y);
  493.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_HitPen, x, y+h, x+w, y+h);
  494.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_HitPen, x, y, x, y+h);
  495.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_HitPen, x+w, y, x+w, y+h);
  496.     }
  497. }
  498.  
  499.  
  500. /****** RTGGadget/RTGGDownRender ******************************************
  501. *
  502. *   NAME
  503. *       RTGGDownRender -- Render gadget in down position
  504. *
  505. *   SYNOPSIS
  506. *       RTGGDownRender(list, akt);
  507. *
  508. *       RTGGDownRender(struct RTGGlist *, struct RTGGadget *);
  509. *
  510. *   FUNCTION
  511. *       Render gadget in down position (i.e. pointer is over gadget and
  512. *       button pressed).
  513. *       This function is called by RefreshRTGGList.
  514. *       It can be replaced by a custom function.
  515. *
  516. *   INPUTS
  517. *       list - pointer ot gadget list
  518. *       akt  - pointer to gadget
  519. *
  520. *
  521. *****************************************************************************
  522. *
  523. */
  524.  
  525. void RTGGDownRender(struct RTGGList *list, struct RTGGadget *akt) {
  526.  
  527.     APTR badr;
  528.     int x,y,w,h;
  529.  
  530.     if (!list) return;
  531.  
  532.     if (akt->rg_DownRender) {
  533.         akt->rg_DownRender(list, akt);
  534.         return;
  535.     }
  536.  
  537.     GetRtgScreenData(list->gl_Screen, ctag);
  538.     badr = GetBufAdr(list->gl_Screen, list->gl_Buffer);
  539.  
  540.     x = akt->rg_Left;
  541.     y = akt->rg_Top;
  542.     w = akt->rg_Width;
  543.     h = akt->rg_Height;
  544.  
  545.     if (ctag[0].ti_Data == grd_Palette) {
  546. /*        DrawRtgLine(list->gl_Screen, badr, akt->rg_DownPen, x, y, x+w, y);
  547.         DrawRtgLine(list->gl_Screen, badr, akt->rg_DownPen, x, y+h, x+w, y+h);
  548.         DrawRtgLine(list->gl_Screen, badr, akt->rg_DownPen, x, y, x, y+h);
  549.         DrawRtgLine(list->gl_Screen, badr, akt->rg_DownPen, x+w, y, x+w, y+h);*/
  550.         DrawRTGBox(list->gl_Screen, badr, x, y, w, h, akt->rg_DownPen);
  551.     } else {
  552.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_DownPen, x, y, x+w, y);
  553.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_DownPen, x, y+h, x+w, y+h);
  554.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_DownPen, x, y, x, y+h);
  555.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_DownPen, x+w, y, x+w, y+h);
  556.     }
  557. }
  558.  
  559.  
  560. /****** RTGGadget/RTGGUpRender ******************************************
  561. *
  562. *   NAME
  563. *       RTGGUpRender -- Render gadget in up position
  564. *
  565. *   SYNOPSIS
  566. *       RTGGUpRender(list, akt);
  567. *
  568. *       RTGGUpRender(struct RTGGlist *, struct RTGGadget *);
  569. *
  570. *   FUNCTION
  571. *       Render gadget in down position (i.e. pointer is not over gadget).
  572. *       This function is called by RefreshRTGGList.
  573. *       It can be replaced by a custom function.
  574. *
  575. *   INPUTS
  576. *       list - pointer ot gadget list
  577. *       akt  - pointer to gadget
  578. *
  579. *****************************************************************************
  580. *
  581. */
  582.  
  583.  
  584. void RTGGUpRender(struct RTGGList *list, struct RTGGadget *akt) {
  585.  
  586.     APTR badr;
  587.     int x,y,w,h;
  588.  
  589.     if (!list) return;
  590.  
  591.     if (akt->rg_UpRender) {
  592.         akt->rg_UpRender(list, akt);
  593.         return;
  594.     }
  595.  
  596.     GetRtgScreenData(list->gl_Screen, ctag);
  597.     badr = GetBufAdr(list->gl_Screen, list->gl_Buffer);
  598.  
  599.     x = akt->rg_Left;
  600.     y = akt->rg_Top;
  601.     w = akt->rg_Width;
  602.     h = akt->rg_Height;
  603.  
  604.     if (ctag[0].ti_Data == grd_Palette) {
  605. /*        DrawRtgLine(list->gl_Screen, badr, akt->rg_UpPen, x, y, x+w, y);
  606.         DrawRtgLine(list->gl_Screen, badr, akt->rg_UpPen, x, y+h, x+w, y+h);
  607.         DrawRtgLine(list->gl_Screen, badr, akt->rg_UpPen, x, y, x, y+h);
  608.         DrawRtgLine(list->gl_Screen, badr, akt->rg_UpPen, x+w, y, x+w, y+h);*/
  609.         DrawRTGBox(list->gl_Screen, badr, x, y, w, h, akt->rg_UpPen);
  610.     } else {
  611.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_UpPen, x, y, x+w, y);
  612.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_UpPen, x, y+h, x+w, y+h);
  613.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_UpPen, x, y, x, y+h);
  614.         DrawRtgLineRGB(list->gl_Screen, badr, akt->rg_UpPen, x+w, y, x+w, y+h);
  615.     }
  616. }
  617.  
  618. /****** RTGGadgets/RefreshRTGGList ******************************************
  619. *
  620. *   NAME   
  621. *       RefreshRTGGList -- Refresh and redraw list of gadgets
  622. *
  623. *   SYNOPSIS
  624. *       RefreshRTGGList(list)
  625. *
  626. *       void RefreshRTGGList(struct RTGGList *);
  627. *
  628. *   FUNCTION
  629. *       Refresh the state of the gadgets in list list and redraw everything.
  630. *
  631. *   INPUTS
  632. *       list - pointer to an RTGGList
  633. *
  634. *****************************************************************************
  635. */
  636.  
  637.  
  638. void RefreshRTGGList(struct RTGGList *list) {
  639.  
  640.     struct RTGGadget *akt;
  641.     int x,y;
  642.     BYTE buffer[10];
  643.  
  644.     if (!list) return;
  645.  
  646.     GetRtgScreenData(list->gl_Screen, mtag);        //  Read mouse
  647.  
  648.     x = mtag[0].ti_Data;
  649.     y = mtag[1].ti_Data;
  650.  
  651.  
  652.     if (!list->gl_First) return;
  653.  
  654.     if (list->gl_Reset) {
  655.         RTGGUpRender(list, list->gl_Reset);
  656.         list->gl_Reset = NULL;
  657.     }
  658.  
  659.     if (RTGInputRecord.LastKey != 0) {              //  Key was pressed
  660.         RTGIe.ie_NextEvent = NULL;
  661.         RTGIe.ie_Class = IECLASS_RAWKEY;
  662.         RTGIe.ie_Code = RTGInputRecord.LastKey;
  663.         RTGIe.ie_Qualifier = 0;
  664.         RTGIe.ie_position.ie_addr = NULL;
  665.         RawKeyConvert(&RTGIe, buffer, 10, NULL);
  666.         RTGInputRecord.LastKey = 0;
  667.  
  668.         for(akt = list->gl_First; akt; akt = akt->rg_Next) {
  669.             if (akt->rg_Key == buffer[0]) {
  670.                 list->gl_Selected = akt;
  671.                 RTGGDownRender(list, akt);
  672.                 list->gl_Reset = akt;
  673.             }
  674.         }
  675.     }
  676.  
  677.     for(akt = list->gl_First; akt; akt = akt->rg_Next)  //  Find akt
  678.         if (RTGGHitTest(akt, x, y)){
  679.             break;
  680.         }
  681.  
  682.     if (akt) {
  683.         if (list->gl_Mode) {                            //  UpMode
  684.             if (akt != list->gl_Hit) {
  685.                 if (list->gl_Hit) RTGGUpRender(list, list->gl_Hit);
  686.                 RTGGHitRender(list, akt);
  687.                 list->gl_Hit = akt;
  688.             }
  689.         } else {                                        //  DownMode
  690.             if ((list->gl_Hit) && RTGGHitTest(list->gl_Hit, x, y)) {
  691.                 RTGGDownRender(list, list->gl_Hit);
  692.             } else {
  693.                 if (list->gl_Hit) RTGGUpRender(list, list->gl_Hit);
  694.             }
  695.         }
  696.     } else {
  697.         if (list->gl_Hit) RTGGUpRender(list, list->gl_Hit);
  698.         if (list->gl_Mode) list->gl_Hit = 0;
  699.     }
  700.  
  701.     if (RTGInputRecord.MK1) {
  702.         list->gl_Mode = FALSE;          //  DownMode
  703.         list->gl_Hit = akt;
  704.         RTGInputRecord.MK1 = 0;
  705.     }
  706.     if (RTGInputRecord.UK1) {
  707.         list->gl_Mode = TRUE;       //  UpMode
  708.         RTGInputRecord.UK1 = 0;
  709.         if (akt == list->gl_Hit) {
  710.             list->gl_Selected = list->gl_Hit;
  711.             list->gl_Hit = NULL;
  712.             if (list->gl_Selected) RTGGUpRender(list, list->gl_Selected);
  713.         }
  714.     }
  715. }
  716.  
  717.  
  718. /****** RTGGadgets/DeleteRTGGList ******************************************
  719. *
  720. *   NAME   
  721. *       DeleteRTGGList -- Delete a list of RTG gadgets
  722. *
  723. *   SYNOPSIS
  724. *       success = DeleteRTGGList(list, force);
  725. *
  726. *       BOOL DeleteRTGGList(struct RTGGList *, BOOL);
  727. *
  728. *   FUNCTION
  729. *       Delete a list of RTG gadgets, including the list header.
  730. *
  731. *   INPUTS
  732. *       list - a pointer to the RTGGList structure to be deleted
  733. *       force - a boolean flag to force the list to be deleted, even if there
  734. *               are gadgets left in it.
  735. *
  736. *   RESULT
  737. *       a boolean value of TRUE indicates successful deletion.
  738. *
  739. *****************************************************************************
  740. */
  741.  
  742.  
  743. BOOL DeleteRTGGList(struct RTGGList *list, BOOL force) {
  744.  
  745.     struct RTGGadget *akt;
  746.     struct RTGGadget *next;
  747.  
  748.     if (!list) return(TRUE);
  749.  
  750.     if ((!force) && (list->gl_First)) return(FALSE);    //  not enforced, and still gadgets in list
  751.  
  752.     akt = list->gl_First;
  753.  
  754.     while (akt) {
  755.         next = akt->rg_Next;
  756.         free(akt);
  757.         akt = next;
  758.     }
  759.  
  760.     free(list);
  761.  
  762.     return(TRUE);
  763. }
  764.  
  765.  
  766. /****** RTGGadgets/RTGGAddIPH ******************************************
  767. *
  768. *   NAME   
  769. *       RTGGAddIPH -- Add Input handler to system
  770. *
  771. *   SYNOPSIS
  772. *       RTGGAddIPH();
  773. *
  774. *       void RTGGAddIPH(void);
  775. *
  776. *   FUNCTION
  777. *       Install input handler
  778. *
  779. *   INPUTS
  780. *
  781. *   RESULT
  782. *
  783. *****************************************************************************
  784. */
  785.  
  786.  
  787. void RTGGAddIPH(void) {
  788.     extern void HandlerCode();
  789.  
  790.     InputHandler.is_Code = HandlerCode;
  791.     InputHandler.is_Data = &RTGInputRecord;
  792.     InputHandler.is_Node.ln_Pri=100;
  793.     InputHandler.is_Node.ln_Name="mygame input handler";
  794.  
  795.     RTGInputIO->io_Data = (APTR)&InputHandler;
  796.     RTGInputIO->io_Command = IND_ADDHANDLER;
  797.     DoIO((struct IORequest *)RTGInputIO);
  798.  
  799.     RTGInputRecord.MK1 = 0;
  800.     RTGInputRecord.UK1 = 0;
  801.     RTGInputRecord.LastKey = 0;
  802.  
  803. }
  804.  
  805.  
  806. /****** RTGGadgets/RTGGRemIPH ******************************************
  807. *
  808. *   NAME
  809. *       RTGGRemIPH -- Remove input handler
  810. *
  811. *   SYNOPSIS
  812. *       RTGGRemIPH();
  813. *
  814. *       void RTGGRemIPH(void);
  815. *
  816. *   FUNCTION
  817. *       Install input handler
  818. *
  819. *   INPUTS
  820. *
  821. *   RESULT
  822. *
  823. *****************************************************************************
  824. */
  825.  
  826.  
  827. void RTGGRemIPH(void) {
  828.     RTGInputIO->io_Data = (APTR)&InputHandler;
  829.     RTGInputIO->io_Command = IND_REMHANDLER;
  830.     DoIO((struct IORequest *)RTGInputIO);
  831. }
  832.  
  833.  
  834. /****** RTGGadgets/RTGGOpenInput ******************************************
  835. *
  836. *   NAME
  837. *       RTGGOpenInput -- Open input device
  838. *
  839. *   SYNOPSIS
  840. *       RTGGOpenInput;
  841. *
  842. *       void RTGGOpenInput(void);
  843. *
  844. *   FUNCTION
  845. *       Open input device
  846. *
  847. *   INPUTS
  848. *
  849. *   RESULT
  850. *
  851. *****************************************************************************
  852. */
  853.  
  854.  
  855. BOOL RTGGOpenInput(void) {
  856.  
  857.     BYTE error;
  858.  
  859.     RTGInputMsgPort = CreatePort(0L, 0L);
  860.     if (!RTGInputMsgPort)
  861.         return(FALSE);
  862.  
  863.     RTGInputIO = (struct IOStdReq *) CreateExtIO(RTGInputMsgPort, sizeof(struct IOStdReq));
  864.     if (!RTGInputIO) {
  865.         DeletePort(RTGInputMsgPort);
  866.         return(FALSE);
  867.     }
  868.  
  869.     error = OpenDevice((STRPTR)"input.device", 0L, (struct IORequest *)RTGInputIO, 0);
  870.     if (error) {
  871.         DeleteExtIO((struct IORequest *)RTGInputIO);
  872.         DeletePort(RTGInputMsgPort);
  873.         return(FALSE);
  874.     }
  875.  
  876.     error = OpenDevice("console.device", -1, (struct IORequest *)&RTGConsoleIO, 0L);
  877.     if (error) {
  878.         CloseDevice((struct IORequest *)RTGInputIO);
  879.         DeleteExtIO((struct IORequest *)RTGInputIO);
  880.         DeletePort(RTGInputMsgPort);
  881.         return(FALSE);
  882.     }
  883.  
  884.     ConsoleDevice = (struct Device *)RTGConsoleIO.io_Device;
  885.  
  886.     return(TRUE);
  887. }
  888.  
  889.  
  890. /****** RTGGadgets/RTGGCloseInput ******************************************
  891. *
  892. *   NAME
  893. *       RTGGCloseInput -- Close input device
  894. *
  895. *   SYNOPSIS
  896. *       RTGGCloseInput;
  897. *
  898. *       void RTGGCloseInput(void);
  899. *
  900. *   FUNCTION
  901. *       Close input device
  902. *
  903. *   INPUTS
  904. *
  905. *   RESULT
  906. *
  907. *****************************************************************************
  908. */
  909.  
  910.  
  911. void RTGGCloseInput(void) {
  912.  
  913.     if (RTGInputIO) {
  914.         if ((BOOL)CheckIO((struct IORequest *)RTGInputIO) == TRUE) {
  915.             AbortIO((struct IORequest *)RTGInputIO);
  916.             WaitIO((struct IORequest *)RTGInputIO);
  917.         }
  918.         CloseDevice((struct IORequest *)RTGInputIO);
  919.         DeleteExtIO((struct IORequest *)RTGInputIO);
  920.         DeletePort(RTGInputMsgPort);
  921.     }
  922.  
  923.     if (ConsoleDevice) {
  924.         CloseDevice((struct IORequest *)&RTGConsoleIO);
  925.         ConsoleDevice = NULL;
  926.     }
  927. }
  928.  
  929.  
  930. /****** RTGGadgets/DrawRTGGList ******************************************
  931. *
  932. *   NAME   
  933. *       DrawRTGGList -- Draw a list of RTG Gadgets in their "up" position
  934. *
  935. *   SYNOPSIS
  936. *       DrawRTGGList(list);
  937. *
  938. *       DrawRTGGList(struct RTGGList *);
  939. *
  940. *   FUNCTION
  941. *       Draw a list of RTG Gadgets in their "up" position :)
  942. *
  943. *   INPUTS
  944. *       list - a pointer to an RTGGList structure
  945. *
  946. *   RESULT
  947. *
  948. *****************************************************************************
  949. */
  950.  
  951. void DrawRTGGList(struct RTGGList *list) {
  952.  
  953.     struct RTGGadget *akt;
  954.  
  955.     if (!list) return;
  956.  
  957.     for(akt = list->gl_First; akt; akt = akt->rg_Next)
  958.         RTGGUpRender(list, akt);
  959.  
  960. }
  961.  
  962.